package com.ccc.netty.server.base;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 基础netty server
 * @author superC
 * @version 1.0.0
 * @date 2022/7/7
 */

@Component
@Slf4j
public class MyNettyServer {

    @Autowired
    private MyHandler myHandler;

    public void run() {
        // 主线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
        // 工作线程组
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        // 一个Netty程序通常由一个Bootstrap开始，主要作用是配置整个Netty程序，串联各个组件
        ServerBootstrap b = new ServerBootstrap(); // (2)
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) // (3)
                .childHandler(new ChannelInitializer<SocketChannel>() { // (4)
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        // 管道
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new StringDecoder());
                        // 添加自定义处理器，处理管道中的数据
                        pipeline.addLast(myHandler);
                    }
                }).option(ChannelOption.SO_BACKLOG, 1024) // (5)
                .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

        // Bind and start to accept incoming connections.
        try {
            ChannelFuture f = b.bind(8400).sync();
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.debug(e.getMessage(), e);
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }

    }
}